package org.six11.ss.server;

import java.io.File;
import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;
import org.six11.ss.server.bean.Sketch;
import org.six11.util.Debug;
import org.six11.util.io.FileUtil;

/**
 * 
 * 
 * @author Gabe Johnson <johnsogg@cmu.edu>
 */
public class ImageBroker extends HttpServlet {

  protected final static SessionFactory sessionFactory;
  static {
    sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();
  }

  public ImageBroker() {
    super();
  }

  protected File getBaseDir() {
    String imgDirStr = getInitParameter("imgDir");
    return new File(imgDirStr);
  }

  protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException,
      IOException {
    // 1: Parse the url string to figure out which image is specified, and what type it is.
    if (req.getPathInfo() == null || req.getPathInfo().length() == 0) {
      return;
    }

    String requestedFile = req.getPathInfo().substring(1);
    String imgDirStr = getInitParameter("imgDir");
    File imgDir = new File(imgDirStr);
    if (!imgDir.exists()) {
      boolean res = imgDir.mkdirs() && imgDir.canRead() && imgDir.canWrite();
      if (res) {
        log("Successfully made path '" + imgDir.getAbsolutePath()
            + "'. All images will be persistently cached there.");
      } else {
        log(" ** Error with image directory '" + imgDir.getAbsolutePath() + "'");
        log(" **   I can't create this directory, or read or write files there.");
        log(" **   This is probably a problem with user permissions. Check which user your web ");
        log(" **   application is running as, and ensure that user can create directories up to ");
        log(" **   and including the one specified in the web.xml file. Bailing.");
        return;
      }
    }
    int typeIdx = requestedFile.indexOf('.');
    int modifyIdx = requestedFile.indexOf('-');
    int idIndexEnd = modifyIdx > 0 ? modifyIdx : typeIdx;
    String idStr = requestedFile.substring(0, idIndexEnd);
    int id = Integer.parseInt(idStr);
    String modify = null;
    if (modifyIdx > 0) {
      modify = requestedFile.substring(modifyIdx + 1, typeIdx);
    }
    String type = requestedFile.substring(typeIdx + 1);
    String contentType = "image/" + type;

    // 2: Check to see if the image file exists. If not, create it.
    File imgFile = new File(imgDir, requestedFile);
    if (!imgFile.exists()) {
      ImageUtil util = new ImageUtil(this);
      if (modify == null) {
        util.generateImage(id, type);
      } else {
        int newSize = Integer.parseInt(modify);
        util.generateImage(id, type, newSize, newSize, imgFile);
      }
      if (!imgFile.exists()) {
        return;
      }
    }

    // 3: Write the file to output using the correct content type.
    resp.setContentType(contentType);
    byte[] fileArray = FileUtil.getBytesFromFile(imgFile);
    ServletOutputStream ros = resp.getOutputStream();
    ros.write(fileArray, 0, fileArray.length);
    ros.close();
  }

  protected Sketch loadSketch(String id) {
    return (Sketch) getHibernate().load(Sketch.class, Integer.parseInt(id));
  }

  protected Session getHibernate() {
    return sessionFactory.getCurrentSession();
  }

  @SuppressWarnings("unused")
  private static void bug(String what) {
    Debug.out("ImageBroker", what);
  }

}
